/*
 * Copyright (c) 2020 Nanjing Xiaoxiongpai Intelligent Technology Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"

#include "lwip/sockets.h"
#include "wifi_connect.h"
// UART
#include "wifiiot_errno.h"
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"
#include "wifiiot_adc.h"
#include "wifiiot_uart.h"

#define UART_TASK_STACK_SIZE 1024 * 8
#define UART_TASK_PRIO 25
#define UART_BUFF_SIZE 1000
//
#define _PROT_ 10006
#define TCP_BACKLOG 10

//在sock_fd 进行监听，在 new_fd 接收新的链接
int sock_fd, new_fd;

char recvbuf[512];
char *buf = "Hello! I'm BearPi-HM_Nano TCP Server!";

static const char *data = "Hello, BearPi!\r\n";

unsigned char checkSum(unsigned char *buff)
{
    unsigned char sum = 0;
    int i;
    for (i = 0; i < buff[2] - 3; i++)
    {
        sum += buff[i];
    }
    return sum;
}

static void TCPServerTask(void)
{

    // UART
    uint8_t uart_buff[UART_BUFF_SIZE] = {0};
    uint8_t *uart_buff_ptr = uart_buff;
    uint32_t ret;

    WifiIotUartAttribute uart_attr = {

        // baud_rate: 9600
        .baudRate = 115200,

        // data_bits: 8bits
        .dataBits = 8,
        .stopBits = 1,
        .parity = 0,
    };

    // Initialize uart driver
    ret = UartInit(WIFI_IOT_UART_IDX_1, &uart_attr, NULL);
    if (ret != WIFI_IOT_SUCCESS)
    {
        printf("Failed to init uart! Err code = %d\n", ret);
        return;
    }
    printf("UART Test Start\n");
    int left_speed_pwm_s = 0;
    int right_speed_pwm_s = 0;

    //

    /* 服务端地址信息 */
    struct sockaddr_in server_sock;
    /* 客户端地址信息 */
    struct sockaddr_in client_sock;
    int sin_size;

    struct sockaddr_in *cli_addr;
    /* 连接Wifi */
    WifiConnect("FSR_EE", "12345678");

    /**
     * 1.创建socket
     * AF_INET:ipv4
     * SOCK_STRAM:tcp协议
     */
    if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        perror("socket is error\r\n");
        exit(1);
    }

    bzero(&server_sock, sizeof(server_sock));
    server_sock.sin_family = AF_INET;
    server_sock.sin_addr.s_addr = htonl(INADDR_ANY);
    server_sock.sin_port = htons(_PROT_);

    /*2.调用bind函数绑定socket和地址*/
    if (bind(sock_fd, (struct sockaddr *)&server_sock, sizeof(struct sockaddr)) == -1)
    {
        perror("bind is error\r\n");
        exit(1);
    }

    /**
     * 3:调用listen函数监听(指定port监听)
     * 通知操作系统区接受来自客户端链接请求
     * 第二个参数：指定队列长度
     */
    if (listen(sock_fd, TCP_BACKLOG) == -1)
    {
        perror("listen is error\r\n");
        exit(1);
    }

    printf("start accept\n");

    /**
     * 4：调用accept函数从队列中
     * 获得一个客户端的请求链接
     */
    while (1)
    {
        sin_size = sizeof(struct sockaddr_in);

        if ((new_fd = accept(sock_fd, (struct sockaddr *)&client_sock, (socklen_t *)&sin_size)) == -1)
        {
            perror("accept");
            continue;
        }

        cli_addr = malloc(sizeof(struct sockaddr));

        printf("accept addr\r\n");

        if (cli_addr != NULL)
        {
            memcpy(cli_addr, &client_sock, sizeof(struct sockaddr));
        }

        //处理目标
        ssize_t ret;
        char a[1] = {1};
        while (1)
        {
            if ((ret = recv(new_fd, recvbuf, sizeof(recvbuf), 0)) == -1)
            {
                printf("recv error \r\n");
            }
            unsigned char buffer[12];
            if (strcmp(recvbuf, "1") == 0)
            {
                //自转
                left_speed_pwm_s = 901;
                right_speed_pwm_s = -901;
                buffer[0] = 0x53;                              // headcode1
                buffer[1] = 0x4b;                              // headcode2
                buffer[2] = 0x0c;                              // 12 all communicate num
                buffer[3] = 0x00;                              // cmd1
                buffer[4] = 0x18;                              // cmd2
                buffer[5] = (char)left_speed_pwm_s;            // data1
                buffer[6] = (char)(left_speed_pwm_s >> 8);     // data2
                buffer[7] = (char)right_speed_pwm_s;           // data3
                buffer[8] = (char)(right_speed_pwm_s >> 8);    // data4
                buffer[9] = checkSum((unsigned char *)buffer); // checksum
                buffer[10] = 0x0d;                             // endcode1
                buffer[11] = 0x0a;                             // endcode2
                UartWrite(WIFI_IOT_UART_IDX_1, &buffer[0], 12);
                // usleep(1000000);
                printf("Yes1\r\n");
            }
            else if (strcmp(recvbuf, "2") == 0)
            {
                //前进
                left_speed_pwm_s = 901;
                right_speed_pwm_s = 901;
                buffer[5] = (char)left_speed_pwm_s;            // data1
                buffer[6] = (char)(left_speed_pwm_s >> 8);     // data2
                buffer[7] = (char)right_speed_pwm_s;           // data3
                buffer[8] = (char)(right_speed_pwm_s >> 8);    // data4
                buffer[9] = checkSum((unsigned char *)buffer); // checksum
                UartWrite(WIFI_IOT_UART_IDX_1, &buffer[0], 12);
                // usleep(1000000);
            }
            else if (strcmp(recvbuf, "0") == 0)
            {
                //停止
                left_speed_pwm_s = 0;
                right_speed_pwm_s = 0;
                buffer[5] = (char)left_speed_pwm_s;            // data1
                buffer[6] = (char)(left_speed_pwm_s >> 8);     // data2
                buffer[7] = (char)right_speed_pwm_s;           // data3
                buffer[8] = (char)(right_speed_pwm_s >> 8);    // data4
                buffer[9] = checkSum((unsigned char *)buffer); // checksum
                UartWrite(WIFI_IOT_UART_IDX_1, &buffer[0], 12);
                // usleep(1000000);
                printf("No\r\n");
            }
            printf("recv :%s\r\n", recvbuf);
            //sleep(2);

            // if ((ret = send(new_fd, buf, strlen(buf) + 1, 0)) == -1)
            // {
            //     perror("send : ");
            // }
            memset(recvbuf, 0, sizeof(recvbuf));
            // recvbuf[0] = '\0';
            //sleep(2);

            UartRead(WIFI_IOT_UART_IDX_1, uart_buff_ptr, UART_BUFF_SIZE);
            printf("Uart1 read data:%s", uart_buff_ptr);
            UartWrite(WIFI_IOT_UART_IDX_1, uart_buff_ptr, sizeof(uart_buff_ptr));
             memset(uart_buff_ptr, 0, sizeof(uart_buff_ptr));
            strcpy(buf,(char *)uart_buff_ptr);
           //memcpy(buf,uart_buff_ptr,1000);
            if ((ret = send(new_fd, uart_buff_ptr, strlen((char*)uart_buff_ptr) + 1, 0)) == -1)
            {
                perror("send : ");
            }
        }

        close(new_fd);
    }
}

static void TCPServerDemo(void)
{
    osThreadAttr_t attr;

    attr.name = "TCPServerTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 10240;
    attr.priority = osPriorityNormal;

    if (osThreadNew((osThreadFunc_t)TCPServerTask, NULL, &attr) == NULL)
    {
        printf("[TCPServerDemo] Falied to create TCPServerTask!\n");
    }
}

APP_FEATURE_INIT(TCPServerDemo);












/*版本存档   */

/*
 * Copyright (c) 2020 Nanjing Xiaoxiongpai Intelligent Technology Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"

#include "lwip/sockets.h"
#include "wifi_connect.h"
// UART
#include "wifiiot_errno.h"
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"
#include "wifiiot_adc.h"
#include "wifiiot_uart.h"

#define UART_TASK_STACK_SIZE 1024 * 8
#define UART_TASK_PRIO 25
#define UART_BUFF_SIZE 1000
//
#define _PROT_ 10006
#define TCP_BACKLOG 10


//wifiap接收数据处理
#define BUFFER_SIZE 4    //最多缓存4包数据
#define MAX_CMD_SIZE 80  //每包最多包含80个字节的数据
//模式选择
#define wifi_uart_test_d   //直接转发模式
#define wifi_uart_test_process   //处理后转发模式
//全局变量用于处理wifiap   双缓冲  数据包处理格式
bool g_bStartBitFlag = 0; //开始接收数据包的标志位
char cmdBuffer[BUFFER_SIZE][MAX_CMD_SIZE]; 缓存数组
 int bufindr = 0; //数据包的读取索引
 int bufindw = 0; //数据包的写入索引
 int buflen  = 0; //缓存中数据包的个数
 const uint16_t package_start_flag_1=0x53;   //数据包头用于检测
  const uint16_t package_start_flag_2=0x4b;   //数据包头用于检测
  const uint16_t package_end_flag = 0x0a;
  int serial_count = 0; //每包数据中的计数变量

  //在sock_fd 进行监听，在 new_fd 接收新的链接
  int sock_fd, new_fd;

  char *check_buf;
  char recvbuf[64];
  char *buf = "Hello! I'm BearPi-HM_Nano TCP Server!";
  char check_rec[12];
  static const char *data = "Hello, BearPi!\r\n";

  unsigned char checkSum(unsigned char *buff)
  {
      unsigned char sum = 0;
      int i;
      for (i = 0; i < buff[2] - 3; i++)
      {
          sum += buff[i];
      }
      return sum;
}

static void TCPServerTask(void)
{

    // UART
    uint8_t uart_buff[UART_BUFF_SIZE] = {0};
    uint8_t *uart_buff_ptr = uart_buff;
    uint32_t ret;

    WifiIotUartAttribute uart_attr = {

        // baud_rate: 9600
        .baudRate = 115200,

        // data_bits: 8bits
        .dataBits = 8,
        .stopBits = 1,
        .parity = 0,
    };

    // Initialize uart driver
    ret = UartInit(WIFI_IOT_UART_IDX_1, &uart_attr, NULL);
    if (ret != WIFI_IOT_SUCCESS)
    {
        printf("Failed to init uart! Err code = %d\n", ret);
        return;
    }
    printf("UART Test Start\n");
    int left_speed_pwm_s = 0;
    int right_speed_pwm_s = 0;

    //

    /* 服务端地址信息 */
    struct sockaddr_in server_sock;
    /* 客户端地址信息 */
    struct sockaddr_in client_sock;
    int sin_size;

    struct sockaddr_in *cli_addr;
    /* 连接Wifi */
    WifiConnect("FSR_EE", "12345678");

    /**
     * 1.创建socket
     * AF_INET:ipv4
     * SOCK_STRAM:tcp协议
     */
    if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        perror("socket is error\r\n");
        exit(1);
    }

    bzero(&server_sock, sizeof(server_sock));
    server_sock.sin_family = AF_INET;
    server_sock.sin_addr.s_addr = htonl(INADDR_ANY);
    server_sock.sin_port = htons(_PROT_);

    /*2.调用bind函数绑定socket和地址*/
    if (bind(sock_fd, (struct sockaddr *)&server_sock, sizeof(struct sockaddr)) == -1)
    {
        perror("bind is error\r\n");
        exit(1);
    }

    /**
     * 3:调用listen函数监听(指定port监听)
     * 通知操作系统区接受来自客户端链接请求
     * 第二个参数：指定队列长度
     */
    if (listen(sock_fd, TCP_BACKLOG) == -1)
    {
        perror("listen is error\r\n");
        exit(1);
    }

    printf("start accept\n");

    /**
     * 4：调用accept函数从队列中
     * 获得一个客户端的请求链接
     */
    while (1)
    {
        sin_size = sizeof(struct sockaddr_in);

        if ((new_fd = accept(sock_fd, (struct sockaddr *)&client_sock, (socklen_t *)&sin_size)) == -1)
        {
            perror("accept");
            continue;
        }

        cli_addr = malloc(sizeof(struct sockaddr));

        printf("accept addr\r\n");

        if (cli_addr != NULL)
        {
            memcpy(cli_addr, &client_sock, sizeof(struct sockaddr));
        }

        //处理目标
        ssize_t ret;
        char a[1] = {1};
        while (1)
        {

            //接收一包数据
           if ((ret = recv(new_fd, recvbuf, sizeof(recvbuf), 0)) == -1)
           {
               printf("recv error \r\n");
           }
          // unsigned char buffer[12];

#ifdef wifi_uart_test_d 
            /*  测试代码  */
            /*  uart接收wifiap直接转发数据情况   如有需要可以直接跳过这部分*/
           UartWrite(WIFI_IOT_UART_IDX_1,(const unsigned char *)recvbuf, sizeof(recvbuf));
            /*endl*/
#endif         

#ifdef wifi_uart_test_process 
        /*测试代码*/
        /*接收wifi并打包数据再做转发   可以衔接其他数据包如来源于串口转发的数据包或者手机端链接wifiap后打包解码的数据包*/
                   //一包数据   

            unsigned char buffer[12];
            
            //手机端TCP简洁指令集 ： 2101 自转  2102  前进
            if (strcmp(recvbuf, "1021") == 0)
            {
                //自转
                left_speed_pwm_s = 901;
                right_speed_pwm_s = -901;
                buffer[0] = 0x53;                              // headcode1
                buffer[1] = 0x4b;                              // headcode2
                buffer[2] = 0x0c;                              // 12 all communicate num
                buffer[3] = 0x00;                              // cmd1
                buffer[4] = 0x18;                              // cmd2
                buffer[5] = (char)left_speed_pwm_s;            // data1
                buffer[6] = (char)(left_speed_pwm_s >> 8);     // data2
                buffer[7] = (char)right_speed_pwm_s;           // data3
                buffer[8] = (char)(right_speed_pwm_s >> 8);    // data4
                buffer[9] = checkSum((unsigned char *)buffer); // checksum
                buffer[10] = 0x0d;                             // endcode1
                buffer[11] = 0x0a;                             // endcode2
                UartWrite(WIFI_IOT_UART_IDX_1, &buffer[0], 12);
                // usleep(1000000);
                printf("Yes1\r\n");
            }
             else if (strcmp(recvbuf, "1022") == 0)
            {
                //前进
                left_speed_pwm_s = 901;
                right_speed_pwm_s = 901;
                buffer[5] = (char)left_speed_pwm_s;            // data1
                buffer[6] = (char)(left_speed_pwm_s >> 8);     // data2
                buffer[7] = (char)right_speed_pwm_s;           // data3
                buffer[8] = (char)(right_speed_pwm_s >> 8);    // data4
                buffer[9] = checkSum((unsigned char *)buffer); // checksum
                UartWrite(WIFI_IOT_UART_IDX_1, &buffer[0], 12);
                // usleep(1000000);
            }
            else if (strcmp(recvbuf, "0") == 0)
            {
                //停止
                left_speed_pwm_s = 0;
                right_speed_pwm_s = 0;
                buffer[5] = (char)left_speed_pwm_s;            // data1
                buffer[6] = (char)(left_speed_pwm_s >> 8);     // data2
                buffer[7] = (char)right_speed_pwm_s;           // data3
                buffer[8] = (char)(right_speed_pwm_s >> 8);    // data4
                buffer[9] = checkSum((unsigned char *)buffer); // checksum
                UartWrite(WIFI_IOT_UART_IDX_1, &buffer[0], 12);
                // usleep(1000000);
                printf("No\r\n");
            }
            printf("recv :%s\r\n", recvbuf);
            //sleep(2);

            // if ((ret = send(new_fd, buf, strlen(buf) + 1, 0)) == -1)
            // {
            //     perror("send : ");
            // }
            memset(recvbuf, 0, sizeof(recvbuf));
            // recvbuf[0] = '\0';
            //sleep(2);

            UartRead(WIFI_IOT_UART_IDX_1, uart_buff_ptr, UART_BUFF_SIZE);
            printf("Uart1 read data:%s", uart_buff_ptr);
            UartWrite(WIFI_IOT_UART_IDX_1, uart_buff_ptr, sizeof(uart_buff_ptr));
             memset(uart_buff_ptr, 0, sizeof(uart_buff_ptr));
            strcpy(buf,(char *)uart_buff_ptr);
           //memcpy(buf,uart_buff_ptr,1000);
            if ((ret = send(new_fd, uart_buff_ptr, strlen((char*)uart_buff_ptr) + 1, 0)) == -1)
            {
                perror("send : ");
            }

            //转发打包NUC下发数据  检查数据头和数据尾
            if(strcmp(recvbuf,(const char *)package_start_flag_1)==0){
                for (int i = 0; i < 12;i++){
                if(strcmp(recvbuf,(const char *)package_end_flag)==0)   break;
                check_buf[i] = recvbuf++;
                }
                UartWrite(WIFI_IOT_UART_IDX_1,(const unsigned char *)check_buf, sizeof(check_buf));
            }
            
        
        /*endl*/
#endif 


        }
        close(new_fd);
    }
}

static void TCPServerDemo(void)
{
    osThreadAttr_t attr;

    attr.name = "TCPServerTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 10240;
    attr.priority = osPriorityNormal;

    if (osThreadNew((osThreadFunc_t)TCPServerTask, NULL, &attr) == NULL)
    {
        printf("[TCPServerDemo] Falied to create TCPServerTask!\n");
    }
}

APP_FEATURE_INIT(TCPServerDemo);
